import subprocess
import json
import re
from pathlib import Path
from typing import Dict, List, Any, Optional
import tempfile
import os
import shutil
from langchain.schema import HumanMessage, SystemMessage
from langchain.chat_models import ChatOpenAI
from doc_loader import VitisHLSDocLoader
import sys

class HLSOptimizer:
    def __init__(self, llm):
        self.llm = llm
        self.doc_loader = VitisHLSDocLoader()

    def optimize(self, code: str) -> str:
        """
        Optimize HLS C++ code using LLM with RAG from Vitis HLS documentation.
        
        Args:
            code (str): The HLS C++ code to optimize
            
        Returns:
            str: The optimized code with pragmas
        """
        # Get relevant documentation context
        context = self.doc_loader.get_relevant_context(code)
        
        # Create system message with documentation context
        system_prompt = f"""You are an expert in HLS optimization for AMD Vitis HLS. Use the following Vitis HLS documentation as reference:

{context}

Your task is to optimize the provided HLS C++ code by:
1. Analyzing the code structure and identifying optimization opportunities
2. Adding appropriate pragmas for:
   - Loop optimizations (pipeline, unroll, etc.)
   - Array partitioning
   - Interface optimizations
   - Data flow optimizations
3. Ensuring the optimizations follow AMD Vitis HLS best practices
4. Providing clear comments explaining the optimizations

Focus on:
- Performance optimization
- Resource utilization
- Interface optimization
- Data flow optimization
- Memory access patterns
- Loop transformations

Return only the optimized code with pragmas and comments."""

        # Create messages for the chat model
        messages = [
            SystemMessage(content=system_prompt),
            HumanMessage(content=f"Please optimize this HLS C++ code:\n\n{code}")
        ]

        # Get optimization from the model
        response = self.llm.invoke(messages)
        return response.content

class HLSExecutor:
    """Handles execution of HLS code using Vitis HLS"""
    
    def __init__(self):
        """Initialize HLS executor"""
        self.vitis_path = self._find_vitis()
        if not self.vitis_path:
            raise RuntimeError(
                "Could not find Vitis command. Please ensure Vitis HLS is installed "
                "and VITIS_PATH environment variable is set or Vitis is in system PATH."
            )
        
        # Initialize environment variables
        self.env = os.environ.copy()
        vitis_bin_dir = os.path.dirname(self.vitis_path)
        if vitis_bin_dir not in self.env['PATH']:
            self.env['PATH'] = f"{vitis_bin_dir};{self.env['PATH']}"
        
        # Initialize analyzer
        self.analyzer = HLSAnalyzer()
        
        # Create config file if it doesn't exist
        self.config_path = Path("hls_config.cfg")
    
    def _find_vitis(self) -> str:
        """Find Vitis executable path"""
        # First check environment variable
        vitis_path = os.environ.get('VITIS_PATH')
        if vitis_path:
            vitis_exe = os.path.join(vitis_path, 'vitis.exe')
            if os.path.exists(vitis_exe):
                return vitis_exe
        
        # Check common installation paths
        common_paths = [
            r'C:\Xilinx\2025.1\Vitis\bin\vitis.exe',
            r'C:\Xilinx\2025.1\Vitis\bin\vitis.bat',
            r'C:\Xilinx\2025.1\Vitis\bin\vitis.cmd',
        ]
        
        for path in common_paths:
            if os.path.exists(path):
                return path
        
        # Try to find in PATH
        try:
            result = subprocess.run(['where', 'vitis'], capture_output=True, text=True)
            if result.returncode == 0:
                return result.stdout.strip().split('\n')[0]
        except Exception:
            pass
        
        return None
    

    
    def _extract_top_function(self, code: str) -> str:
        """Extract the top function name from the synthesis code"""
        # Look for function declarations
        import re
        # Match function declarations like: void function_name(...)
        pattern = r'void\s+(\w+)\s*\('
        matches = re.findall(pattern, code)
        if matches:
            return matches[0]  # Return the first function name found
        raise RuntimeError("No function declaration found in the synthesis code")

    def execute(self, hls_code: str, testbench_code: str = None, header_code: str = None) -> dict:
        """Execute HLS code and return results"""
        # Create temporary directory for HLS files
        temp_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'temp_hls')
        os.makedirs(temp_dir, exist_ok=True)
        
        # Clean up the code by removing any natural language text
        hls_code = self._clean_code(hls_code)
        if testbench_code:
            testbench_code = self._clean_code(testbench_code)
        if header_code:
            header_code = self._clean_code(header_code)
        
        # Extract top function name from the synthesis code
        top_function = self._extract_top_function(hls_code)
        print(f"Found top function: {top_function}")
        
        # Create synthesis file with top function name
        syn_file = os.path.join(temp_dir, f'{top_function}.cpp')
        with open(syn_file, 'w', encoding='utf-8') as f:
            f.write(hls_code)
        
        # Create testbench file if provided
        tb_file = None
        if testbench_code:
            tb_file = os.path.join(temp_dir, f'{top_function}_tb.cpp')
            with open(tb_file, 'w', encoding='utf-8') as f:
                f.write(testbench_code)
        
        # Create header file if provided
        header_file = None
        if header_code:
            header_file = os.path.join(temp_dir, f'{top_function}.h')
            with open(header_file, 'w', encoding='utf-8') as f:
                f.write(header_code)
        
        # Copy run.py to temp directory
        run_py = os.path.join(temp_dir, 'run.py')
        shutil.copy2(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'run.py'), run_py)
        
        # Verify files were created
        if not os.path.exists(syn_file):
            raise RuntimeError(f"Synthesis file was not created at {syn_file}")
        if testbench_code and not os.path.exists(tb_file):
            raise RuntimeError(f"Testbench file was not created at {tb_file}")
        if header_code and not os.path.exists(header_file):
            raise RuntimeError(f"Header file was not created at {header_file}")
        
        # Debug information
        print(f"Current working directory: {os.getcwd()}")
        print(f"Temporary directory: {temp_dir}")
        print(f"Synthesis file: {syn_file} (exists: {os.path.exists(syn_file)})")
        if tb_file:
            print(f"Testbench file: {tb_file} (exists: {os.path.exists(tb_file)})")
        if header_file:
            print(f"Header file: {header_file} (exists: {os.path.exists(header_file)})")
        
        # Execute HLS process
        try:
            # Run HLS process
            cmd = [self.vitis_path, '-s', 'run.py', syn_file]
            if tb_file:
                cmd.append(tb_file)
            cmd.append(top_function)  # Use the extracted top function name
            
            print(f"Executing command: {' '.join(cmd)}")
            result = subprocess.run(
                cmd,
                capture_output=True,
                text=True,
                cwd=temp_dir
            )
            
            # Parse results
            return self.analyzer.analyze(result.stdout, result.stderr)
            
        except Exception as e:
            print(f"Error executing HLS: {str(e)}")
            print(f"Current directory: {os.getcwd()}")
            print(f"Temporary directory: {temp_dir}")
            print(f"Synthesis file: {syn_file} (exists: {os.path.exists(syn_file)})")
            if tb_file:
                print(f"Testbench file: {tb_file} (exists: {os.path.exists(tb_file)})")
            if header_file:
                print(f"Header file: {header_file} (exists: {os.path.exists(header_file)})")
            raise
        finally:
            # Clean up temporary files
            try:
                # Add a small delay to ensure files are not in use
                import time
                time.sleep(1)
                
                # Try to delete files first
                if os.path.exists(syn_file):
                    os.remove(syn_file)
                if tb_file and os.path.exists(tb_file):
                    os.remove(tb_file)
                if header_file and os.path.exists(header_file):
                    os.remove(header_file)
                if os.path.exists(run_py):
                    os.remove(run_py)
                
                # Then try to remove the directory
                if os.path.exists(temp_dir):
                    os.rmdir(temp_dir)
            except Exception as e:
                print(f"Warning: Could not clean up temporary files: {str(e)}")
                # Continue execution even if cleanup fails
    
    def execute_project(self, project_folder: str) -> dict:
        """Execute HLS project from an existing project folder"""
        if not os.path.exists(project_folder):
            raise RuntimeError(f"Project folder does not exist: {project_folder}")
        
        run_py_path = os.path.join(project_folder, 'run.py')
        if not os.path.exists(run_py_path):
            raise RuntimeError(f"run.py not found in project folder: {project_folder}")
        
        print(f"Executing HLS project: {project_folder}")
        print(f"Run script: {run_py_path}")
        
        try:
            # Execute the run.py script
            cmd = [self.vitis_path, '-s', 'run.py']
            
            print(f"Executing command: {' '.join(cmd)}")
            print(f"Working directory: {project_folder}")
            
            result = subprocess.run(
                cmd,
                capture_output=True,
                text=True,
                cwd=project_folder
            )
            
            print(f"Command completed with return code: {result.returncode}")
            
            # Parse results using the project folder context
            return self.analyzer.analyze_project(result.stdout, result.stderr, project_folder)
            
        except Exception as e:
            print(f"Error executing project: {str(e)}")
            raise
    
    def _clean_code(self, code: str) -> str:
        """Clean up code by removing natural language text and markdown formatting"""
        # Remove markdown code block markers
        code = code.replace('```cpp', '').replace('```', '')
        
        # Remove any natural language text before the first #include or #define
        lines = code.split('\n')
        start_idx = 0
        for i, line in enumerate(lines):
            if line.strip().startswith(('#include', '#define', 'void', 'int', 'float', 'double', 'char')):
                start_idx = i
                break
        
        # Remove any natural language text after the last closing brace
        end_idx = len(lines)
        for i in range(len(lines) - 1, -1, -1):
            if '}' in lines[i]:
                end_idx = i + 1
                break
        
        # Join the cleaned lines
        return '\n'.join(lines[start_idx:end_idx])

class HLSAnalyzer:
    """Analyzes HLS execution results"""
    
    def analyze(self, stdout: str, stderr: str) -> dict:
        """
        Analyze HLS execution results.
        
        Args:
            stdout (str): Standard output from HLS execution
            stderr (str): Standard error from HLS execution
            
        Returns:
            dict: Analysis results including status and messages
        """
        result = {
            "status": "success" if not stderr else "error",
            "stdout": stdout,
            "stderr": stderr,
            "messages": [],
            "csim_report": "",
            "syn_report": {}
        }
        
        # Add stdout messages
        if stdout:
            result["messages"].extend(stdout.split('\n'))
        
        # Add stderr messages
        if stderr:
            result["messages"].extend(stderr.split('\n'))
        
        # Read CSIM report
        csim_log_path = os.path.join("temp_hls", "workspace", "matmul_partition", "matmul_partition", "hls", "csim", "report", "matmul_partition_csim.log")
        if os.path.exists(csim_log_path):
            try:
                with open(csim_log_path, 'r', encoding='utf-8') as f:
                    result["csim_report"] = f.read()
            except Exception as e:
                print(f"Error reading CSIM report: {str(e)}")
        
        # Read SYN report
        syn_rpt_path = os.path.join("temp_hls", "workspace", "matmul_partition", "matmul_partition", "hls", "syn", "report", "matmul_partition_csynth.rpt")
        if os.path.exists(syn_rpt_path):
            try:
                with open(syn_rpt_path, 'r', encoding='utf-8') as f:
                    syn_content = f.read()
                    
                    # Extract Performance Estimates
                    perf_start = syn_content.find("== Performance Estimates")
                    if perf_start != -1:
                        perf_end = syn_content.find("== Utilization Estimates", perf_start)
                        if perf_end != -1:
                            perf_section = syn_content[perf_start:perf_end]
                            # Extract Timing Summary
                            timing_start = perf_section.find("+ Timing:")
                            timing_end = perf_section.find("+ Latency:", timing_start)
                            if timing_start != -1 and timing_end != -1:
                                result["syn_report"]["performance"] = perf_section[timing_start:timing_end]
                    
                    # Extract Utilization Estimates
                    util_start = syn_content.find("== Utilization Estimates")
                    if util_start != -1:
                        util_end = syn_content.find("== Interface", util_start)
                        if util_end != -1:
                            util_section = syn_content[util_start:util_end]
                            # Extract Summary
                            summary_start = util_section.find("* Summary:")
                            if summary_start != -1:
                                result["syn_report"]["utilization"] = util_section[summary_start:]
            except Exception as e:
                print(f"Error reading SYN report: {str(e)}")
        
        return result 
    
    def analyze_project(self, stdout: str, stderr: str, project_folder: str) -> dict:
        """
        Analyze HLS execution results from a project folder.
        
        Args:
            stdout (str): Standard output from HLS execution
            stderr (str): Standard error from HLS execution
            project_folder (str): Path to the project folder
            
        Returns:
            dict: Analysis results including status and messages
        """
        result = {
            "status": "success" if not stderr else "error",
            "stdout": stdout,
            "stderr": stderr,
            "messages": [],
            "csim_report": "",
            "syn_report": {}
        }
        
        # Add stdout messages
        if stdout:
            result["messages"].extend(stdout.split('\n'))
        
        # Add stderr messages
        if stderr:
            result["messages"].extend(stderr.split('\n'))
        
        print(f"Analyzing project folder: {project_folder}")
        
        # Look for workspace directory in the project folder
        workspace_dir = os.path.join(project_folder, 'workspace')
        print(f"Looking for workspace directory: {workspace_dir}")
        print(f"Workspace directory exists: {os.path.exists(workspace_dir)}")
        
        if os.path.exists(workspace_dir):
            # Look for component directory
            try:
                component_dirs = [d for d in os.listdir(workspace_dir) 
                                if os.path.isdir(os.path.join(workspace_dir, d))]
                print(f"Found component directories: {component_dirs}")
                
                if component_dirs:
                    component_name = component_dirs[0]  # Use first component found
                    component_path = os.path.join(workspace_dir, component_name)
                    print(f"Using component: {component_name}")
                    print(f"Component path: {component_path}")
                    
                    # Try to find report files with different patterns
                    self._find_and_read_reports(result, component_path, component_name)
                    
            except Exception as e:
                print(f"Error exploring workspace directory: {str(e)}")
                result["messages"].append(f"Error exploring workspace: {str(e)}")
        else:
            result["messages"].append(f"Workspace directory not found: {workspace_dir}")
        
        return result
    
    def check_existing_reports(self, project_folder: str) -> dict:
        """
        Check if CSIM and synthesis reports already exist in the project folder.
        
        Args:
            project_folder (str): Path to the project folder
            
        Returns:
            dict: Information about existing reports
        """
        report_status = {
            'csim_exists': False,
            'csim_path': '',
            'syn_exists': False,
            'syn_path': ''
        }
        
        print(f"Checking for existing reports in: {project_folder}")
        
        # Look for workspace directory
        workspace_dir = os.path.join(project_folder, 'workspace')
        if not os.path.exists(workspace_dir):
            print(f"Workspace directory not found: {workspace_dir}")
            return report_status
        
        try:
            # Look for component directory
            component_dirs = [d for d in os.listdir(workspace_dir) 
                            if os.path.isdir(os.path.join(workspace_dir, d))]
            
            if not component_dirs:
                print("No component directories found in workspace")
                return report_status
            
            component_name = component_dirs[0]  # Use first component found
            component_path = os.path.join(workspace_dir, component_name)
            
            # Extract function name from component name
            function_name = component_name.replace('_autogen', '') if component_name.endswith('_autogen') else component_name
            
            print(f"Checking component: {component_name}, function: {function_name}")
            
            # Check for CSIM report
            possible_csim_paths = [
                os.path.join(component_path, component_name, "hls", "csim", "report", f"{function_name}_csim.log"),
                os.path.join(component_path, component_name, "hls", "csim", "report", f"{component_name}_csim.log"),
                os.path.join(component_path, "hls", "csim", "report", f"{function_name}_csim.log"),
                os.path.join(component_path, "hls", "csim", "report", f"{component_name}_csim.log"),
            ]
            
            for csim_path in possible_csim_paths:
                if os.path.exists(csim_path):
                    report_status['csim_exists'] = True
                    report_status['csim_path'] = os.path.relpath(csim_path, project_folder)
                    print(f"Found CSIM report: {csim_path}")
                    break
            
            # If no direct path found, check directories for any csim log files
            if not report_status['csim_exists']:
                possible_csim_dirs = [
                    os.path.join(component_path, component_name, "hls", "csim", "report"),
                    os.path.join(component_path, "hls", "csim", "report"),
                ]
                
                for csim_dir in possible_csim_dirs:
                    if os.path.isdir(csim_dir):
                        try:
                            files = os.listdir(csim_dir)
                            csim_files = [f for f in files if f.endswith('_csim.log') or f == 'csim.log']
                            if csim_files:
                                csim_file_path = os.path.join(csim_dir, csim_files[0])
                                report_status['csim_exists'] = True
                                report_status['csim_path'] = os.path.relpath(csim_file_path, project_folder)
                                print(f"Found CSIM report in directory: {csim_file_path}")
                                break
                        except Exception as e:
                            print(f"Error checking directory {csim_dir}: {str(e)}")
            
            # Check for synthesis report
            possible_syn_paths = [
                os.path.join(component_path, component_name, "hls", "syn", "report", f"{function_name}_csynth.rpt"),
                os.path.join(component_path, component_name, "hls", "syn", "report", f"{component_name}_csynth.rpt"),
                os.path.join(component_path, component_name, "hls", "syn", "report", "csynth.rpt"),
                os.path.join(component_path, "hls", "syn", "report", f"{function_name}_csynth.rpt"),
                os.path.join(component_path, "hls", "syn", "report", f"{component_name}_csynth.rpt"),
                os.path.join(component_path, "hls", "syn", "report", "csynth.rpt"),
            ]
            
            for syn_path in possible_syn_paths:
                if os.path.exists(syn_path):
                    report_status['syn_exists'] = True
                    report_status['syn_path'] = os.path.relpath(syn_path, project_folder)
                    print(f"Found synthesis report: {syn_path}")
                    break
            
            # If no direct path found, check directories for any synthesis report files
            if not report_status['syn_exists']:
                possible_syn_dirs = [
                    os.path.join(component_path, component_name, "hls", "syn", "report"),
                    os.path.join(component_path, "hls", "syn", "report"),
                ]
                
                for syn_dir in possible_syn_dirs:
                    if os.path.isdir(syn_dir):
                        try:
                            files = os.listdir(syn_dir)
                            syn_files = [f for f in files if f.endswith('_csynth.rpt') or f == 'csynth.rpt']
                            if syn_files:
                                # Prefer function-specific report
                                preferred_file = None
                                for syn_file in syn_files:
                                    if function_name in syn_file:
                                        preferred_file = syn_file
                                        break
                                if not preferred_file:
                                    preferred_file = syn_files[0]
                                
                                syn_file_path = os.path.join(syn_dir, preferred_file)
                                report_status['syn_exists'] = True
                                report_status['syn_path'] = os.path.relpath(syn_file_path, project_folder)
                                print(f"Found synthesis report in directory: {syn_file_path}")
                                break
                        except Exception as e:
                            print(f"Error checking directory {syn_dir}: {str(e)}")
        
        except Exception as e:
            print(f"Error checking for existing reports: {str(e)}")
        
        return report_status
    
    def _find_and_read_reports(self, result: dict, component_path: str, component_name: str):
        """Find and read CSIM and SYN reports with flexible path searching"""
        
        # Extract function name from component name (remove _autogen suffix if present)
        function_name = component_name.replace('_autogen', '')
        if component_name.endswith('_autogen'):
            function_name = component_name[:-8]  # Remove '_autogen'
        else:
            function_name = component_name
        
        print(f"Searching for reports with component_name: {component_name}, function_name: {function_name}")
        
        # Search for CSIM report - multiple possible paths and filenames
        possible_csim_paths = [
            # Pattern: workspace/component_name/component_name/hls/csim/report/function_name_csim.log
            os.path.join(component_path, component_name, "hls", "csim", "report", f"{function_name}_csim.log"),
            os.path.join(component_path, component_name, "hls", "csim", "report", f"{component_name}_csim.log"),
            # Pattern: workspace/component_name/hls/csim/report/function_name_csim.log
            os.path.join(component_path, "hls", "csim", "report", f"{function_name}_csim.log"),
            os.path.join(component_path, "hls", "csim", "report", f"{component_name}_csim.log"),
            # Check for any *_csim.log files
            os.path.join(component_path, component_name, "hls", "csim", "report"),
            os.path.join(component_path, "hls", "csim", "report"),
        ]
        
        for csim_path in possible_csim_paths:
            print(f"Trying CSIM path: {csim_path}")
            
            # If it's a directory, look for any csim log files
            if os.path.isdir(csim_path):
                try:
                    files = os.listdir(csim_path)
                    csim_files = [f for f in files if f.endswith('_csim.log') or f == 'csim.log']
                    print(f"Found CSIM files in directory: {csim_files}")
                    
                    if csim_files:
                        # Use the first CSIM file found
                        csim_file_path = os.path.join(csim_path, csim_files[0])
                        try:
                            with open(csim_file_path, 'r', encoding='utf-8') as f:
                                result["csim_report"] = f.read()
                            print(f"Successfully read CSIM report from: {csim_file_path}")
                            break
                        except Exception as e:
                            print(f"Error reading CSIM report from {csim_file_path}: {str(e)}")
                except Exception as e:
                    print(f"Error listing directory {csim_path}: {str(e)}")
            
            # If it's a file path, try to read it directly
            elif os.path.exists(csim_path):
                try:
                    with open(csim_path, 'r', encoding='utf-8') as f:
                        result["csim_report"] = f.read()
                    print(f"Successfully read CSIM report from: {csim_path}")
                    break
                except Exception as e:
                    print(f"Error reading CSIM report from {csim_path}: {str(e)}")
            else:
                print(f"CSIM path not found: {csim_path}")
        
        # Search for SYN report - multiple possible paths and filenames
        possible_syn_paths = [
            # Pattern: workspace/component_name/component_name/hls/syn/report/function_name_csynth.rpt
            os.path.join(component_path, component_name, "hls", "syn", "report", f"{function_name}_csynth.rpt"),
            os.path.join(component_path, component_name, "hls", "syn", "report", f"{component_name}_csynth.rpt"),
            os.path.join(component_path, component_name, "hls", "syn", "report", "csynth.rpt"),
            # Pattern: workspace/component_name/hls/syn/report/function_name_csynth.rpt
            os.path.join(component_path, "hls", "syn", "report", f"{function_name}_csynth.rpt"),
            os.path.join(component_path, "hls", "syn", "report", f"{component_name}_csynth.rpt"),
            os.path.join(component_path, "hls", "syn", "report", "csynth.rpt"),
            # Check for any *_csynth.rpt files
            os.path.join(component_path, component_name, "hls", "syn", "report"),
            os.path.join(component_path, "hls", "syn", "report"),
        ]
        
        for syn_path in possible_syn_paths:
            print(f"Trying SYN path: {syn_path}")
            
            # If it's a directory, look for any synthesis report files
            if os.path.isdir(syn_path):
                try:
                    files = os.listdir(syn_path)
                    syn_files = [f for f in files if f.endswith('_csynth.rpt') or f == 'csynth.rpt']
                    print(f"Found SYN files in directory: {syn_files}")
                    
                    if syn_files:
                        # Prefer function-specific report, fallback to generic csynth.rpt
                        preferred_file = None
                        for syn_file in syn_files:
                            if function_name in syn_file:
                                preferred_file = syn_file
                                break
                        if not preferred_file:
                            preferred_file = syn_files[0]
                        
                        syn_file_path = os.path.join(syn_path, preferred_file)
                        print(f"Using SYN report file: {syn_file_path}")
                        
                        try:
                            with open(syn_file_path, 'r', encoding='utf-8') as f:
                                syn_content = f.read()
                                self._extract_synthesis_reports(result, syn_content)
                            print(f"Successfully read SYN report from: {syn_file_path}")
                            break
                        except Exception as e:
                            print(f"Error reading SYN report from {syn_file_path}: {str(e)}")
                except Exception as e:
                    print(f"Error listing directory {syn_path}: {str(e)}")
            
            # If it's a file path, try to read it directly
            elif os.path.exists(syn_path):
                try:
                    with open(syn_path, 'r', encoding='utf-8') as f:
                        syn_content = f.read()
                        self._extract_synthesis_reports(result, syn_content)
                    print(f"Successfully read SYN report from: {syn_path}")
                    break
                except Exception as e:
                    print(f"Error reading SYN report from {syn_path}: {str(e)}")
            else:
                print(f"SYN path not found: {syn_path}")
        
        # If no reports found, list directory contents for debugging
        if not result["csim_report"] and not result["syn_report"]:
            print("No reports found. Listing directory contents for debugging:")
            self._debug_directory_structure(component_path)
    
    def _extract_synthesis_reports(self, result: dict, syn_content: str):
        """Extract performance and utilization information from synthesis report"""
        # Extract Performance Estimates
        perf_start = syn_content.find("== Performance Estimates")
        if perf_start != -1:
            perf_end = syn_content.find("== Utilization Estimates", perf_start)
            if perf_end != -1:
                perf_section = syn_content[perf_start:perf_end]
                result["syn_report"]["performance"] = perf_section
                print("Successfully extracted performance estimates")
        
        # Extract Utilization Estimates
        util_start = syn_content.find("== Utilization Estimates")
        if util_start != -1:
            util_end = syn_content.find("== Interface", util_start)
            if util_end != -1:
                util_section = syn_content[util_start:util_end]
                result["syn_report"]["utilization"] = util_section
                print("Successfully extracted utilization estimates")
            else:
                # If no Interface section found, take the rest
                result["syn_report"]["utilization"] = syn_content[util_start:]
                print("Successfully extracted utilization estimates (no Interface section)")
    
    def _debug_directory_structure(self, base_path: str, max_depth: int = 3, current_depth: int = 0):
        """Debug helper to print directory structure"""
        if current_depth > max_depth:
            return
        
        indent = "  " * current_depth
        try:
            if os.path.exists(base_path):
                print(f"{indent}{os.path.basename(base_path)}/")
                for item in os.listdir(base_path):
                    item_path = os.path.join(base_path, item)
                    if os.path.isdir(item_path):
                        self._debug_directory_structure(item_path, max_depth, current_depth + 1)
                    else:
                        print(f"{indent}  {item}")
            else:
                print(f"{indent}[Path does not exist: {base_path}]")
        except Exception as e:
            print(f"{indent}[Error accessing {base_path}: {str(e)}]")